05779ceabcf73bb74c1b533e4eb4c502a3bacc8b,src/heros/alias/FieldSensitiveIFDSSolver.java,FieldSensitiveIFDSSolver,processCall,#PathEdge#,209

Before Change


		for (N returnSiteN : returnSiteNs) {
			FlowFunction<FieldRef, D> callToReturnFlowFunction = flowFunctions.getCallToReturnFlowFunction(n, returnSiteN);
			for(AnnotatedFact<FieldRef, D> d3: computeCallToReturnFlowFunction(callToReturnFlowFunction, d1, d2))
				propagate(d1, returnSiteN, d3.getFact(), n, false);
		}
	}

After Change


	 * @param edge an edge whose target node resembles a method call
	 */
	private void processCall(PathEdge<N,D> edge) {
		final D d1 = edge.factAtSource();
		final N n = edge.getTarget(); // a call node; line 14...

        logger.trace("Processing call to {}", n);

		final D d2 = edge.factAtTarget();
		assert d2 != null;
		Collection<N> returnSiteNs = icfg.getReturnSitesOfCallAt(n);
		
		//for each possible callee
		Collection<M> callees = icfg.getCalleesOfCallAt(n);
		for(M sCalledProcN: callees) { //still line 14
			//compute the call-flow function
			FlowFunction<FieldRef, D> function = flowFunctions.getCallFlowFunction(n, sCalledProcN);
			Set<AnnotatedFact<FieldRef, D>> res = computeCallFlowFunction(function, d1, d2);
			
			Collection<N> startPointsOf = icfg.getStartPointsOf(sCalledProcN);
			//for each result node of the call-flow function
			for(AnnotatedFact<FieldRef, D> d3: res) {
				//for each callee's start point(s)
				for(N sP: startPointsOf) {
					//create initial self-loop
					D abstractStartPointFact = d3.getFact().cloneWithAccessPath(new AccessPath<FieldRef>());
					propagate(new PathEdge<>(abstractStartPointFact, sP, abstractStartPointFact), n, false); //line 15
				}
				
				//register the fact that <sp,d3> has an incoming edge from <n,d2>
				//line 15.1 of Naeem/Lhotak/Rodriguez
				IncomingEdge<D, N> incomingEdge = new IncomingEdge<D, N>(d3.getFact(),n,d1,d2);
				if (!addIncoming(sCalledProcN, incomingEdge))
					continue;
				
				resumeEdges(sCalledProcN, d3.getFact());
				registerInterestedCaller(sCalledProcN, incomingEdge);
				
				
				//line 15.2
				Set<SummaryEdge<D, N>> endSumm = endSummary(sCalledProcN, d3.getFact());
					
				//still line 15.2 of Naeem/Lhotak/Rodriguez
				//for each already-queried exit value <eP,d4> reachable from <sP,d3>,
				//create new caller-side jump functions to the return sites
				//because we have observed a potentially new incoming edge into <sP,d3>
				if (endSumm != null)
					for(SummaryEdge<D, N> summary: endSumm) {
						if(AccessPathUtil.isPrefixOf(summary.getSourceFact(), d3.getFact())) {
							Optional<D> d4 = AccessPathUtil.applyAbstractedSummary(d3.getFact(), summary);
							if(d4.isPresent()) {
								//for each return site
								for(N retSiteN: returnSiteNs) {
									//compute return-flow function
									FlowFunction<FieldRef, D> retFunction = flowFunctions.getReturnFlowFunction(n, sCalledProcN, summary.getTargetStmt(), retSiteN);
									//for each target value of the function
									for(AnnotatedFact<FieldRef, D> d5: computeReturnFlowFunction(retFunction, d4.get(), n)) {
										D d5p_restoredCtx = restoreContextOnReturnedFact(d2, d5.getFact());
										propagate(new PathEdge<>(d1, retSiteN, d5p_restoredCtx), n, false);
									}
								}
							}
						} 
					}
			}
		}
		//line 17-19 of Naeem/Lhotak/Rodriguez		
		//process intra-procedural flows along call-to-return flow functions
		for (N returnSiteN : returnSiteNs) {
			FlowFunction<FieldRef, D> callToReturnFlowFunction = flowFunctions.getCallToReturnFlowFunction(n, returnSiteN);
			for(AnnotatedFact<FieldRef, D> d3: computeCallToReturnFlowFunction(callToReturnFlowFunction, d1, d2))
				propagate(new PathEdge<>(d1, returnSiteN, d3.getFact()), n, false);
		}
	}